import 'dart:core';
import 'dart:collection';
void main() {
  
  
//https://dart.cn/libraries/dart-core/#numbers
//https://dart.cn/libraries/dart-core/#printing-to-the-console
  print('I drink tea.');
  // 字符串转换为数字
  assert(int.parse('42') == 42);
  assert(int.parse('0x42') == 66);
  assert(double.parse('0.50') == 0.5);

assert(num.parse('42') is int);
assert(num.parse('0x42') is int);
assert(num.parse('0.50') is double);


  // 数字转换为字符串
  assert(42.toString() == '42');
  assert(123.456.toString() == '123.456');
  assert(123.456.toStringAsFixed(2) == '123.46');
  assert(123.456.toStringAsPrecision(2) == '1.2e+2');
  assert(double.parse('1.2e+2') == 120.0);

  print('All assertions passed!');



//https://dart.cn/libraries/dart-core/#strings-and-regular-expressions
// Check whether a string contains another string.
assert('Never odd or even'.contains('odd'));

// Does a string start with another string?
assert('Never odd or even'.startsWith('Never'));

// Does a string end with another string?
assert('Never odd or even'.endsWith('even'));

// Find the location of a string inside a string.
assert('Never odd or even'.indexOf('odd') == 6);




//https://dart.cn/libraries/dart-core/#extracting-data-from-a-string
// Grab a substring.
assert('Never odd or even'.substring(6, 9) == 'odd');

// Split a string using a string pattern.
var parts = 'progressive web apps'.split(' ');
assert(parts.length == 3);
assert(parts[0] == 'progressive');

// Get a UTF-16 code unit (as a string) by index.
assert('Never odd or even'[0] == 'N');

// Use split() with an empty string parameter to get
// a list of all characters (as Strings); good for
// iterating.
for (final char in 'hello'.split('')) {
  print(char);
}

// Get all the UTF-16 code units in the string.
var codeUnitList = 'Never odd or even'.codeUnits.toList();
assert(codeUnitList[0] == 78);






//https://dart.cn/libraries/dart-core/#converting-to-uppercase-or-lowercase
// Convert to uppercase.
assert('web apps'.toUpperCase() == 'WEB APPS');

// Convert to lowercase.
assert('WEB APPS'.toLowerCase() == 'web apps');




//https://dart.cn/libraries/dart-core/#trimming-and-empty-strings
// Trim a string.
assert('  hello  '.trim() == 'hello');

// Check whether a string is empty.
assert(''.isEmpty);

// Strings with only white space are not empty.
assert('  '.isNotEmpty);





//https://dart.cn/libraries/dart-core/#replacing-part-of-a-string
var greetingTemplate = 'Hello, NAME!';
var greeting = greetingTemplate.replaceAll(RegExp('NAME'), 'Bob');

// greetingTemplate didn't change.
assert(greeting != greetingTemplate);





//https://dart.cn/libraries/dart-core/#building-a-string
var sb = StringBuffer();
sb
  ..write('Use a StringBuffer for ')
  ..writeAll(['efficient', 'string', 'creation'], ' ')
  ..write('.');

var fullString = sb.toString();

assert(fullString == 'Use a StringBuffer for efficient string creation.');




//https://dart.cn/libraries/dart-core/#regular-expressions
// Here's a regular expression for one or more digits.
var digitSequence = RegExp(r'\d+');

var lettersOnly = 'llamas live fifteen to twenty years';
var someDigits = 'llamas live 15 to 20 years';

// contains() can use a regular expression.
assert(!lettersOnly.contains(digitSequence));
assert(someDigits.contains(digitSequence));

// Replace every match with another string.
var exedOut = someDigits.replaceAll(digitSequence, 'XX');
assert(exedOut == 'llamas live XX to XX years');



var digitSequence01 = RegExp(r'\d+');
var someDigits01 = 'llamas live 15 to 20 years';

// Check whether the reg exp has a match in a string.
assert(digitSequence01.hasMatch(someDigits01));

// Loop through all matches.
for (final match in digitSequence.allMatches(someDigits)) {
  print(match.group(0)); // 15, then 20


}





//https://dart.cn/libraries/dart-core/#collections
// 使用 String 的方法
  String text = "  Hello, Dart!  ";
  print(text.trim()); // 去除前后空格：Hello, Dart!
  print(text.toLowerCase()); // 转换为小写：  hello, dart!  
  print(text.split(',')); // 按逗号分割：["  Hello", " Dart!  "]


// List 示例
  List<String> fruits = ['Apple', 'Banana', 'Orange'];
  print(fruits[0]); // 输出：Apple

  // Set 示例
  Set<int> numbers = {1, 2, 3, 3}; // 重复元素会被忽略
  print(numbers); // 输出：{1, 2, 3}

  // Map 示例
  Map<String, int> scores = {'Alice': 90, 'Bob': 85};
  print(scores['Alice']); // 输出：90









//https://dart.cn/libraries/dart-core/#lists
// Create an empty list of strings.
var grains = <String>[];
assert(grains.isEmpty);

// Create a list using a list literal.
var fruits01 = ['apples', 'oranges'];

// Add to a list.
fruits01.add('kiwis');

// Add multiple items to a list.
fruits01.addAll(['grapes', 'bananas']);

// Get the list length.
assert(fruits01.length == 5);

// Remove a single item.
var appleIndex = fruits01.indexOf('apples');
fruits01.removeAt(appleIndex);
assert(fruits01.length == 4);

// Remove all elements from a list.
fruits01.clear();
assert(fruits01.isEmpty);

// You can also create a List using one of the constructors.
var vegetables = List.filled(99, 'broccoli');
assert(vegetables.every((v) => v == 'broccoli'));



var fruits02 = ['apples', 'oranges'];
// Access a list item by index.
assert(fruits02[0] == 'apples');

// Find an item in a list.
assert(fruits02.indexOf('apples') == 0);


var fruits03 = ['bananas', 'apples', 'oranges'];
// Sort a list.
fruits03.sort((a, b) => a.compareTo(b));
assert(fruits03[0] == 'apples');


// This list should contain only strings.
var fruits04 = <String>[];

fruits04.add('apples');
var fruit = fruits04[0];







//https://dart.cn/libraries/dart-core/#sets
// Create an empty set of strings.
var ingredients = <String>{};

// Add new items to it.
ingredients.addAll(['gold', 'titanium', 'xenon']);
assert(ingredients.length == 3);

// Adding a duplicate item has no effect.
ingredients.add('gold');
assert(ingredients.length == 3);

// Remove an item from a set.
ingredients.remove('gold');
assert(ingredients.length == 2);

// You can also create sets using
// one of the constructors.
var atomicNumbers01 = Set.from([79, 22, 54]);





var ingredients01 = Set<String>();
ingredients01.addAll(['gold', 'titanium', 'xenon']);

// Check whether an item is in the set.
assert(ingredients.contains('titanium'));

// Check whether all the items are in the set.
assert(ingredients.containsAll(['titanium', 'xenon']));



var ingredients02 = Set<String>();
ingredients02.addAll(['gold', 'titanium', 'xenon']);

// Create the intersection of two sets.
var nobleGases = Set.from(['xenon', 'argon']);
var intersection = ingredients02.intersection(nobleGases);
assert(intersection.length == 1);
assert(intersection.contains('xenon'));






//https://dart.cn/libraries/dart-core/#maps
// Maps often use strings as keys.
var hawaiianBeaches = {
  'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'],
  'Big Island': ['Wailea Bay', 'Pololu Beach'],
  'Kauai': ['Hanalei', 'Poipu'],
};

// Maps can be built from a constructor.
var searchTerms = Map();

// Maps are parameterized types; you can specify what
// types the key and value should be.
var nobleGases01 = Map<int, String>();



var nobleGases02 = {54: 'xenon'};

// Retrieve a value with a key.
assert(nobleGases02[54] == 'xenon');



// Remove a key and its value.
nobleGases.remove(54);
assert(!nobleGases01.containsKey(54));




var hawaiianBeaches01 = {
  'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'],
  'Big Island': ['Wailea Bay', 'Pololu Beach'],
  'Kauai': ['Hanalei', 'Poipu'],
};

// Get all the keys as an unordered collection
// (an Iterable).
var keys = hawaiianBeaches01.keys;

assert(keys.length == 3);
assert(Set.from(keys).contains('Oahu'));

// Get all the values as an unordered collection
// (an Iterable of Lists).
var values = hawaiianBeaches01.values;
assert(values.length == 3);
assert(values.any((v) => v.contains('Waikiki')));

var hawaiianBeaches02 = {
  'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'],
  'Big Island': ['Wailea Bay', 'Pololu Beach'],
  'Kauai': ['Hanalei', 'Poipu'],
};




//https://dart.cn/libraries/dart-core/#common-collection-methods
var coffees = <String>[];
var teas = ['green', 'black', 'chamomile', 'earl grey'];
assert(coffees.isEmpty);
assert(teas.isNotEmpty);

var teas01 = ['green', 'black', 'chamomile', 'earl grey'];

teas01.forEach((tea) => print('I drink $tea'));

hawaiianBeaches.forEach((k, v) {
  print('I want to visit $k and swim at $v');
  // I want to visit Oahu and swim at
  // [Waikiki, Kailua, Waimanalo], etc.
});


var teas02 = ['green', 'black', 'chamomile', 'earl grey'];

var loudTeas = teas02.map((tea) => tea.toUpperCase());
loudTeas.forEach(print);
var loudTeas02 = teas02.map((tea) => tea.toUpperCase()).toList();


var teas03 = ['green', 'black', 'chamomile', 'earl grey'];

// Chamomile is not caffeinated.
bool isDecaffeinated(String teaName) => teaName == 'chamomile';

// Use where() to find only the items that return true
// from the provided function.
var decaffeinatedTeas01 = teas03.where((tea) => isDecaffeinated(tea));
// or teas.where(isDecaffeinated)

// Use any() to check whether at least one item in the
// collection satisfies a condition.
assert(teas.any(isDecaffeinated));

// Use every() to check whether all the items in a
// collection satisfy a condition.
assert(!teas.every(isDecaffeinated));





//https://dart.cn/libraries/dart-core/#encoding-and-decoding-fully-qualified-uris
var uri = 'https://example.org/api?foo=some message';

var encoded = Uri.encodeFull(uri);
assert(encoded == 'https://example.org/api?foo=some%20message');

var decoded = Uri.decodeFull(encoded);
assert(uri == decoded);


//https://dart.cn/libraries/dart-core/#encoding-and-decoding-uri-components

var uri01 = 'https://example.org/api?foo=some message';

var encoded02 = Uri.encodeComponent(uri01);
assert(
  encoded02 == 'https%3A%2F%2Fexample.org%2Fapi%3Ffoo%3Dsome%20message',
);
var decoded01 = Uri.decodeComponent(encoded);
assert(uri == decoded01);





//https://dart.cn/libraries/dart-core/#parsing-uris
//var uri= Uri.parse('https://example.org:8080/foo/bar#frag');

//assert(uri.scheme == 'https');
//assert(uri.host == 'example.org');
//assert(uri.path == '/foo/bar');
//assert(uri.fragment == 'frag');
//assert(uri.origin == 'https://example.org:8080');




var uri02 = Uri(
  scheme: 'https',
  host: 'example.org',
  path: '/foo/bar',
  fragment: 'frag',
  queryParameters: {'lang': 'dart'},
);
//assert(Uri.toString() == 'https://example.org/foo/bar?lang=dart#frag');


var httpUri = Uri.http('example.org', '/foo/bar', {'lang': 'dart'});
var httpsUri = Uri.https('example.org', '/foo/bar', {'lang': 'dart'});

assert(httpUri.toString() == 'http://example.org/foo/bar?lang=dart');
assert(httpsUri.toString() == 'https://example.org/foo/bar?lang=dart');






//https://dart.cn/libraries/dart-core/#dates-and-times
// Get the current date and time.
//var now = DateTime.now();

// Create a new DateTime with the local time zone.
//var y2k = DateTime(2000); // January 1, 2000

// Specify the month and day.
//y2k = DateTime(2000, 1, 2); // January 2, 2000

// Specify the date as a UTC time.
//y2k = DateTime.utc(2000); // 1/1/2000, UTC

// Specify a date and time in ms since the Unix epoch.
//y2k = DateTime.fromMillisecondsSinceEpoch(946684800000, isUtc: true);

// Parse an ISO 8601 date in the UTC time zone.
//y2k = DateTime.parse('2000-01-01T00:00:00Z');

// Create a new DateTime from an existing one, adjusting just some properties:
//var sameTimeLastYear = now.copyWith(year: now.year - 1);





//var y2k01 = DateTime.utc(2000);
// Add one year.
//var y2001 = y2k.add(const Duration(days: 366));
//assert(y2001.year == 2001);

// Subtract 30 days.
//var december2000 = y2001.subtract(const Duration(days: 30));
//assert(december2000.year == 2000);
//assert(december2000.month == 12);

// Calculate the difference between two dates.
// Returns a Duration object.
//var duration = y2001.difference(y2k);
//assert(duration.inDays == 366); // y2k was a leap year.





//https://dart.cn/libraries/dart-core/#comparing-objects
var short = const Line(1);
  var long = const Line(100);
  assert(short.compareTo(long) < 0);





//https://dart.cn/libraries/dart-core/#implementing-map-keys

  var p1 = Person01('Bob', 'Smith');
  var p2 = Person01('Bob', 'Smith');
  var p3 = 'not a person';
  assert(p1.hashCode == p2.hashCode);
  assert(p1 == p2);
  assert(p1 != p3);


//https://dart.cn/libraries/dart-core/#iteration
for (final process in Processes()) {
    print(process);
  }







//https://dart.cn/libraries/dart-core/#weak-references-and-finalizers
Object? obj = Object();
  var weakRef = WeakReference(obj);

  print(weakRef.target); // 输出: Instance of 'Object'

  obj = null; // 解除对对象的强引用
  // 强制触发垃圾回收（在 Dart 中通常不需要手动调用）
  // 等待垃圾回收
  print(weakRef.target); // 输出: null（对象已被回收）

}



//https://dart.cn/libraries/dart-core/#comparing-objects
class Line implements Comparable<Line> {
  final int length;
  const Line(this.length);

  @override
  int compareTo(Line other) => length - other.length;
}



//https://dart.cn/libraries/dart-core/#implementing-map-keys
class Person01 {
  final String firstName, lastName;

  Person01(this.firstName, this.lastName);

  // Override hashCode using the static hashing methods
  // provided by the `Object` class.
  @override
  int get hashCode => Object.hash(firstName, lastName);

  // You should generally implement operator `==` if you
  // override `hashCode`.
  @override
  bool operator ==(Object other) {
    return other is Person01 &&
        other.firstName == firstName &&
        other.lastName == lastName;
  }
}





//https://dart.cn/libraries/dart-core/#iteration
class Process {
  final int id;
  final String name;

  Process(this.id, this.name);

  @override
  String toString() => 'Process(id: $id, name: $name)';
}

class ProcessIterator implements Iterator<Process> {
  final List<Process> _processes;
  int _currentIndex = -1;

  ProcessIterator(this._processes);

  @override
  Process get current => _processes[_currentIndex];

  @override
  bool moveNext() {
    if (_currentIndex < _processes.length - 1) {
      _currentIndex++;
      return true;
    }
    return false;
  }
}

class Processes extends IterableBase<Process> {
  final List<Process> _processes = [
    Process(1, 'Process 1'),
    Process(2, 'Process 2'),
    Process(3, 'Process 3'),
  ];

  @override
  Iterator<Process> get iterator => ProcessIterator(_processes);
}



//https://dart.cn/libraries/dart-core/#exceptions
class FooException implements Exception {
  final String? msg;

  const FooException([this.msg]);

  @override
  String toString() => msg ?? 'FooException';
}





